/**
  ******************************************************************************
  * File Name          : measure.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention : 注意单位!!! 
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "bsp.h"
#include "tskcfg.h"
#include "measure.h"
#include "parameter.h"
#include <stdlib.h>
#include "gui.h"

double gm_flowrate_theory_0d1g_0d01s = 0.0;   /* 理论流量 */

static inline void meas_calgm_init(GlobalVariablesStru *pgv)
{
  gm_flowrate_theory_0d1g_0d01s = 0.0;
  
  pgv->ir.meas_ca.calgm_wtfactor_adjust = 0;
  pgv->ir.meas_ca.calgm_wtfactor_correct = 0;
  pgv->ir.meas_ca.calgm_belt_remainder_mm = 0;
  pgv->ir.meas_ca.calgm_belt_remainder_0d01s = 0;
  pgv->ir.meas_ca.calgm_elapsed_time_0d01s = 0;
  pgv->ir.meas_ca.calgm_elapsed_pulse = 0;
  pgv->ir.meas_ca.calgm_actual_total_0d1g = 0;
  pgv->ir.meas_ca.calgm_theory_total_0d1g = 0;

  pgv->ir.meas_ca.calibrate_timeout = 0;

  pgv->co.meas_ec.cal_guama_save_seg_key = 0;
  pgv->co.meas_ec.cal_guama_save_all_key = 0;

  pgv->di.meas_is.calgm_msg = 0;
}

static inline Meas_ReturnEnum meas_calgm_process(double flowrate_0d1g_0d01s, GlobalVariablesStru *pgv)
{
  float ppl_0d1mm;                     /* 单位长度的脉冲数 */
  float belt_elapsed_len_0d1mm;
  double double_wtfactor_adjust;       /* 调整的系数 */
  double double_theory_total_0d1g;     /* 理论累计量 */
  uint64_t belt_len_pulse;

  pgv->ir.meas_ca.calgm_elapsed_time_0d01s++;                         /* 流逝的时间,以0.01s为单位 */
  pgv->ir.meas_ca.calgm_elapsed_pulse += pgv->ir.meas_ad.sad_100hz;   /* 累加速度脉冲数 */
  pgv->ir.meas_ca.calgm_actual_total_0d1g += flowrate_0d1g_0d01s;            /* 累计量 */
  
  /* 理论累计量计算: (皮带总长/称量段长)*砝码重量 */
  double_theory_total_0d1g = ((double)pgv->hr.meas_pa.belt_length_mm / (double)pgv->hr.meas_pa.effect_length_mm) * (double)pgv->hr.meas_pa.cal_fama_weight_0d1g;
  pgv->ir.meas_ca.calgm_theory_total_0d1g = double_theory_total_0d1g;

  if(pgv->hr.meas_pa.len_circle_mode == MEAS_LEN_CIRCLE_FIXLENG)
  {
    /* 定长模式下,当皮带运行过的长度等于皮带周长时,完成一次挂码校验 */
    ppl_0d1mm = (float)pgv->hr.meas_pa.speed_wheel_pls / (float)pgv->hr.meas_pa.speed_wheel_cir_0d1mm;     /* 计算单位长度(0.1mm)的脉冲数 */
    belt_len_pulse = ((float)pgv->hr.meas_pa.belt_length_mm * 10.0) * ppl_0d1mm;                           /* 将皮带长度转换为脉冲的数量  */

    belt_elapsed_len_0d1mm = (float)pgv->ir.meas_ca.calgm_elapsed_pulse / ppl_0d1mm;                   /* 计算皮带转过的长度 */
    pgv->ir.meas_ca.calgm_belt_remainder_mm = pgv->hr.meas_pa.belt_length_mm - (belt_elapsed_len_0d1mm / 10.0);  /* 计算皮带剩余的长度 */

    if(pgv->ir.meas_ca.calgm_elapsed_pulse >= belt_len_pulse)
    {
      if(pgv->ir.meas_ca.calgm_actual_total_0d1g <= 0)
      {
        return RET_FAIL; /* 挂码校验失败 */
      }

      if(pgv->hr.meas_pa.effect_length_mm <= 0)
      {
        return RET_FAIL; /* 挂码校验失败 */
      }

      gm_flowrate_theory_0d1g_0d01s = double_theory_total_0d1g / pgv->ir.meas_ca.calgm_elapsed_time_0d01s; /* 计算理论流量 */

      /* 两个重量单位必须一致,否则新k不对 */
      double_wtfactor_adjust = (double)pgv->hr.meas_pa.weight_factor_base * ((double_theory_total_0d1g) / (double)pgv->ir.meas_ca.calgm_actual_total_0d1g);
      pgv->ir.meas_ca.calgm_wtfactor_adjust = double_wtfactor_adjust;
      
      if((double_wtfactor_adjust - pgv->ir.meas_ca.calgm_wtfactor_adjust) >= 0.5)
      {
        pgv->ir.meas_ca.calgm_wtfactor_adjust++;
      }

      if(pgv->ir.meas_ca.calgm_wtfactor_adjust == 0)
      {
        return RET_FAIL;  /* 挂码校验失败 */
      }

      return RET_SUCCESS; /* 挂码校验完成 */
    }
  }
  else
  {
    /* 定时模式下,当皮带运行过的时间等于皮带周期时,完成一次挂码校验 */
    pgv->ir.meas_ca.calgm_belt_remainder_0d01s = pgv->hr.meas_pa.belt_period_0d01s - pgv->ir.meas_ca.calgm_elapsed_time_0d01s;

    if(pgv->ir.meas_ca.calgm_elapsed_time_0d01s >= pgv->hr.meas_pa.belt_period_0d01s)
    {
      if(pgv->ir.meas_ca.calgm_actual_total_0d1g <= 0)
      {
        return RET_FAIL; /* 挂码校验失败 */
      }

      if(pgv->hr.meas_pa.effect_length_mm <= 0)
      {
        return RET_FAIL; /* 挂码校验失败 */
      }

      gm_flowrate_theory_0d1g_0d01s = double_theory_total_0d1g / pgv->ir.meas_ca.calgm_elapsed_time_0d01s; /* 计算理论流量 */

      /* 两个重量单位必须一致,否则新k不对 */
      double_wtfactor_adjust = (double)pgv->hr.meas_pa.weight_factor_base * ((double_theory_total_0d1g) / (double)pgv->ir.meas_ca.calgm_actual_total_0d1g);
      pgv->ir.meas_ca.calgm_wtfactor_adjust = double_wtfactor_adjust;
      
      if((double_wtfactor_adjust - pgv->ir.meas_ca.calgm_wtfactor_adjust) >= 0.5)
      {
        pgv->ir.meas_ca.calgm_wtfactor_adjust++;
      }

      if(pgv->ir.meas_ca.calgm_wtfactor_adjust == 0)
      {
        return RET_FAIL; /* 挂码校验失败 */
      }

      return RET_SUCCESS; /* 挂码校验完成 */
    }
  }

  return RET_RUNNING;
}

static Meas_ReturnEnum meas_calgm_waitsave(GlobalVariablesStru *pgv)
{
  if(pgv->co.meas_ec.cal_guama_save_seg_key == 1) /* 修正标定 */
  {
    pgv->co.meas_ec.cal_guama_save_seg_key = 0;

    pgv->ir.meas_ca.calgm_wtfactor_correct = pgv->ir.meas_ca.calgm_wtfactor_adjust - pgv->hr.meas_pa.weight_factor_base;  /* 计算修正值 */
    
    if(gm_flowrate_theory_0d1g_0d01s <= (400.0/F_MUL_0D1G_0D01S_TO_TH))
    {
      sto_update_item(sto_mtidx(weight_factor05), (const Sto_CellUnion *)&pgv->ir.meas_ca.calgm_wtfactor_correct, 5);
    }
    else if((gm_flowrate_theory_0d1g_0d01s > (400.0/F_MUL_0D1G_0D01S_TO_TH)) && (gm_flowrate_theory_0d1g_0d01s <= (800.0/F_MUL_0D1G_0D01S_TO_TH)))
    {
      sto_update_item(sto_mtidx(weight_factor04), (const Sto_CellUnion *)&pgv->ir.meas_ca.calgm_wtfactor_correct, 5);
    }
    else if((gm_flowrate_theory_0d1g_0d01s > (800.0/F_MUL_0D1G_0D01S_TO_TH)) && (gm_flowrate_theory_0d1g_0d01s <= (1200.0/F_MUL_0D1G_0D01S_TO_TH)))
    {
      sto_update_item(sto_mtidx(weight_factor03), (const Sto_CellUnion *)&pgv->ir.meas_ca.calgm_wtfactor_correct, 5);
    }
    else if((gm_flowrate_theory_0d1g_0d01s > (1200.0/F_MUL_0D1G_0D01S_TO_TH)) && (gm_flowrate_theory_0d1g_0d01s <= (1600.0/F_MUL_0D1G_0D01S_TO_TH)))
    {
      sto_update_item(sto_mtidx(weight_factor02), (const Sto_CellUnion *)&pgv->ir.meas_ca.calgm_wtfactor_correct, 5);
    }
    else if(gm_flowrate_theory_0d1g_0d01s > (1600.0/F_MUL_0D1G_0D01S_TO_TH))
    {
      sto_update_item(sto_mtidx(weight_factor01), (const Sto_CellUnion *)&pgv->ir.meas_ca.calgm_wtfactor_correct, 5);
    }

    pgv->ir.meas_ca.calibrate_timeout = 0;

    return RET_SUCCESS;
  }
  
  if(pgv->co.meas_ec.cal_guama_save_all_key == 1) /* 基础标定 */
  {
    pgv->co.meas_ec.cal_guama_save_all_key = 0;
    
    sto_update_item(sto_mtidx(weight_factor_base), (const Sto_CellUnion *)&pgv->ir.meas_ca.calgm_wtfactor_adjust, 5);

    pgv->ir.meas_ca.calibrate_timeout = 0;

    return RET_SUCCESS;
  }
  
  if(pgv->ir.meas_ca.calibrate_timeout++ >= MEAS_CALIBRATE_WATI_SAVE_TIMEOUT)
  {
    return RET_FAIL;
  }

  return RET_RUNNING;
}

static inline void meas_calgm_exit(GlobalVariablesStru *pgv)
{
  pgv->ir.meas_ca.calibrate_timeout = 0;
}

Meas_ReturnEnum meas_calibrate_guama(double flowrate_0d1g_0d01s, GlobalVariablesStru *pgv)
{
  uint8_t res;
  Meas_ReturnEnum ret;
  Gui_CmdQueStru scmd;

  ret = RET_RUNNING;

  if(pgv->co.meas_ec.cal_guama_stop_key == 1)
  {
    pgv->co.meas_ec.cal_guama_stop_key = 0;
    pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_SENDMSG;
    pgv->di.meas_is.calgm_msg = 1;
  }

  switch (pgv->ir.meas_ca.calgm_substmachine)
  {
    case CALGM_SUB_STATE_MACHINE_INIT:
      meas_calgm_init(pgv);
      pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_PROCESS;

    case CALGM_SUB_STATE_MACHINE_PROCESS:
      res = meas_calgm_process(flowrate_0d1g_0d01s, pgv);
      if(res == RET_SUCCESS)
      {
        pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_WAITSAVE;
        xQueueSend(gui_cmd_qhd, &gui_cmd_go_calgmend, 2);   /* 切换校验完成页面 */
      }
      else if(res == RET_FAIL)
      {
        pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_SENDMSG;
        pgv->di.meas_is.calgm_msg = 2;
        break;
      }
      else
      {
        break;
      }

    case CALGM_SUB_STATE_MACHINE_WAITSAVE:
      res = meas_calgm_waitsave(pgv);
      if(res == RET_SUCCESS)
      {
        pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_SENDMSG;
        pgv->di.meas_is.calgm_msg = 3;
      }
      else if(res == RET_FAIL)
      {
        pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_SENDMSG;
        pgv->di.meas_is.calgm_msg = 4;
      }
      else
      {
        break;
      }

    case CALGM_SUB_STATE_MACHINE_SENDMSG:
      pgv->ir.meas_ca.calgm_substmachine = CALGM_SUB_STATE_MACHINE_EXIT;
      scmd.cmd = GUI_CMD_CHANGE_FORM;
      scmd.key = IRKEY_KEY_VALUE_NULL;
      scmd.toform = &gui_from_calmessage;
      scmd.msg = pgv->di.meas_is.calgm_msg;
      xQueueSend(gui_cmd_qhd, &scmd, 2);

    default:
    case CALGM_SUB_STATE_MACHINE_EXIT:
      meas_calgm_exit(pgv);
      return RET_EXIT;
  }

  return ret;
}
